﻿using Lucene.Net.Analysis;
using Lucene.Net.Analysis.Standard;
using Lucene.Net.Documents;
using Lucene.Net.Index;
using Lucene.Net.QueryParsers;
using Lucene.Net.Search;
using Lucene.Net.Store;
using Lucene.Net.Util;
using PanGu;
using PanGu.Lucene.Analyzer;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace lucene_test
{
    public partial class Form1 : Form
    {
        private string[] _coulumnNames =
        {
            "ORGID","ORGCODE","ORGNAME","SHORTNAME",/*"GLOBALPCCODE",
            "PARENTORGID","TELEPHONE","FAX","URL","CORPORATIONTYPE",
            "REGISTERFUND","WORKINGSCOPE","STATUS","REGIONCODE","CITYCODE",
            "SALESCHANNELID","TARGETTYPE","EMAIL","ADDRESS","ZIPCODE",
            "HOSPITALLEVEL","BUSINESSLICENSE","BUSINESSCERTIFICATE","CONTACTNAME","COUNTYCODE",*/
            "REGIONNAME","CITYNAME","COUNTYNAME"/*,"REGISTERNO","CHAINTYPE",
            "GRADENAME","PARITYFLAG","MEDICAREFLAG","OUTPATIENTSQTY","BEDSQTY",
            "DATASOURCE","CHANNEL","GLOBALPCNAME","LATESTTIME","POPCHANNEL"*/
        };

        public Form1()
        {
            InitializeComponent();
        }

        private void btnAddIndex_Click(object sender, EventArgs e)
        {

        }

        private IndexWriter GetIndexWriter()
        {
            var dir = FSDirectory.Open(@"D:\Index");
            //Analyzer analyzer = new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_30);
            Analyzer analyzer = new PanGuAnalyzer();
            bool isCreate = !IndexReader.IndexExists(dir);
            var writer = new IndexWriter(dir, analyzer, isCreate, IndexWriter.MaxFieldLength.UNLIMITED);
            return writer;
        }

        private void btnQuery_Click(object sender, EventArgs e)
        {
            string keyWord = txtKeyWord.Text.Trim();

            dataGridView1.DataSource = Search(keyWord);
        }

        private DataTable Search(string q)
        {
            IndexReader reader = DirectoryReader.Open(FSDirectory.Open(@"D:\Index"), true);
            var searcher = new IndexSearcher(reader);

            //创建查询
            PerFieldAnalyzerWrapper wrapper = new PerFieldAnalyzerWrapper(new PanGuAnalyzer());
            for (int i = 0; i < _coulumnNames.Length; i++)
            {
                wrapper.AddAnalyzer(_coulumnNames[0], new PanGuAnalyzer());
            }

            QueryParser parser = new MultiFieldQueryParser(Lucene.Net.Util.Version.LUCENE_30, _coulumnNames, wrapper);
            Query query = parser.Parse(q);
            
            TopScoreDocCollector collector = TopScoreDocCollector.Create(20, true);//10--查询条数

            searcher.Search(query, collector);
            var hits = collector.TopDocs().ScoreDocs;

            DataTable dt = new DataTable();
            for (int i = 0; i < _coulumnNames.Length; i++)
            {
                dt.Columns.Add(_coulumnNames[i]);
            }

            foreach (var hit in hits)
            {
                var document = searcher.Doc(hit.Doc);
                var dr = dt.NewRow();
                for (int i = 0; i < _coulumnNames.Length; i++)
                {
                    dr[_coulumnNames[i]] = document.Get(_coulumnNames[i]);
                }
                dt.Rows.Add(dr);
            }

            return dt;
        }

        #region 从索引搜索结果
        /// <summary>
        /// 从索引搜索结果
        /// </summary>
        public List<Model.article> SearchIndex(string Words, int PageSize, int PageIndex, out int _totalcount)
        {
            _totalcount = 0;
            Dictionary<string, string> dic = new Dictionary<string, string>();
            BooleanQuery bQuery = new BooleanQuery();
            string title = string.Empty;
            string content = string.Empty;
            title = GetKeyWordsSplitBySpace(Words);
            QueryParser parse = new QueryParser(Lucene.Net.Util.Version.LUCENE_29, "title", new PanGuAnalyzer());
            Query query = parse.Parse(title);
            parse.SetDefaultOperator(QueryParser.Operator.AND);
            bQuery.Add(query, BooleanClause.Occur.SHOULD);
            dic.Add("title", Words);

            content = GetKeyWordsSplitBySpace(Words);
            QueryParser parseC = new QueryParser(Lucene.Net.Util.Version.LUCENE_29, "content", new PanGuAnalyzer());
            Query queryC = parseC.Parse(content);
            parseC.SetDefaultOperator(QueryParser.Operator.AND);
            bQuery.Add(queryC, BooleanClause.Occur.SHOULD);
            dic.Add("content", Words);
            if (bQuery != null && bQuery.GetClauses().Length > 0)
            {
                return GetSearchResult(bQuery, dic, PageSize, PageIndex, out _totalcount);
            }
            return null;
        }
        /// <summary>
        /// 获取
        /// </summary>
        /// <param name="bQuery"></param>
        private List<Model.article> GetSearchResult(BooleanQuery bQuery, Dictionary<string, string> dicKeywords, int PageSize, int PageIndex, out int totalCount)
        {
            List<Model.article> list = new List<Model.article>();
            FSDirectory directory = FSDirectory.Open(new DirectoryInfo(IndexDic), new NoLockFactory());
            IndexReader reader = IndexReader.Open(directory, true);
            IndexSearcher searcher = new IndexSearcher(reader);
            TopScoreDocCollector collector = TopScoreDocCollector.create(1000, true);
            Sort sort = new Sort(new SortField("Addtime", SortField.DOC, true));
            searcher.Search(bQuery, null, collector);
            totalCount = collector.GetTotalHits();//返回总条数
            TopDocs docs = searcher.Search(bQuery, (Filter)null, PageSize * PageIndex, sort);
            if (docs != null && docs.totalHits > 0)
            {
                for (int i = 0; i < docs.totalHits; i++)
                {
                    if (i >= (PageIndex - 1) * PageSize && i < PageIndex * PageSize)
                    {
                        Document doc = searcher.Doc(docs.scoreDocs[i].doc);
                        Model.article model = new Model.article()
                        {
                            id = int.Parse(doc.Get("number").ToString()),
                            title = doc.Get("title").ToString(),
                            content = doc.Get("content").ToString(),
                            add_time = DateTime.Parse(doc.Get("Addtime").ToString()),
                            channel_id = int.Parse(doc.Get("channel_id").ToString())
                        };
                        list.Add(SetHighlighter(dicKeywords, model));
                    }
                }
            }
            return list;
        }
        /// <summary>
        /// 设置关键字高亮
        /// </summary>
        /// <param name="dicKeywords">关键字列表</param>
        /// <param name="model">返回的数据模型</param>
        /// <returns></returns>
        private Model.article SetHighlighter(Dictionary<string, string> dicKeywords, Model.article model)
        {
            SimpleHTMLFormatter simpleHTMLFormatter = new PanGu.HighLight.SimpleHTMLFormatter("<font color=\"red\">", "</font>");
            Highlighter highlighter = new PanGu.HighLight.Highlighter(simpleHTMLFormatter, new Segment());
            highlighter.FragmentSize = 250;
            string strTitle = string.Empty;
            string strContent = string.Empty;
            dicKeywords.TryGetValue("title", out strTitle);
            dicKeywords.TryGetValue("content", out strContent);
            if (!string.IsNullOrEmpty(strTitle))
            {
                string title = model.title;
                model.title = highlighter.GetBestFragment(strTitle, model.title);
                if (string.IsNullOrEmpty(model.title))
                {
                    model.title = title;
                }
            }
            if (!string.IsNullOrEmpty(strContent))
            {
                string content = model.content;
                model.content = highlighter.GetBestFragment(strContent, model.content);
                if (string.IsNullOrEmpty(model.content))
                {
                    model.content = content;
                }
            }
            return model;
        }
        /// <summary>
        /// 处理关键字为索引格式
        /// </summary>
        /// <param name="keywords"></param>
        /// <returns></returns>
        private string GetKeyWordsSplitBySpace(string keywords)
        {
            PanGuTokenizer ktTokenizer = new PanGuTokenizer();
            StringBuilder result = new StringBuilder();
            ICollection<WordInfo> words = ktTokenizer.SegmentToWordInfos(keywords);
            foreach (WordInfo word in words)
            {
                if (word == null)
                {
                    continue;
                }
                result.AppendFormat("{0}^{1}.0 ", word.Word, (int)Math.Pow(3, word.Rank));
            }
            return result.ToString().Trim();
        }
        #endregion
    }
}
